#include "StdAfx.h"
#include "IlluminatedObject.h"

IlluminatedObject::IlluminatedObject(void)
{
	strcpy(fs_path, "../Resources/Shaders/LightingShaderFS.fs");
	strcpy(vs_path, "../Resources/Shaders/LightingShaderVS.vs");
	lightColor = Vector3(1 ,1, 1);
}

IlluminatedObject::~IlluminatedObject(void)
{
}

int IlluminatedObject::Load(char* file_nfg, char* file_tga, char* file_normal_tga, Vector3 light_pos)
{
	int Res = Object::Load(file_nfg, file_tga);
	myShaders.getUniformLocation("u_light_position", lightPositionUniform);
	myShaders.getUniformLocation("u_light_color", lightColorUniform);
	myShaders.getUniformLocation("u_normalmap", normalMapUniform);
	myShaders.getAttributeLocation("a_tangentL", tangentAttribute);
	myShaders.getAttributeLocation("a_bitangentL", bitangentAttribute);
	setNormalMap(file_normal_tga);
	setLightPosition(light_pos);
	return LOAD_SUCCEEDED;
}

void IlluminatedObject::Draw( ESContext *esContext, Camera * camera)
{
	glUseProgram(myShaders.program);
	// Open buffer
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

	// Bind Vertex to Shaders
	glEnableVertexAttribArray(myShaders.positionAttribute);
	glVertexAttribPointer(myShaders.positionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

	// Bind norm to Shaders
	glEnableVertexAttribArray(myShaders.normalAttribute);
	glVertexAttribPointer(myShaders.normalAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*) 0 + 2 * sizeof(Vector3) + sizeof(Vector2) + sizeof(Vector4));
	// Bind tangent to Shaders
	glEnableVertexAttribArray(tangentAttribute);
	glVertexAttribPointer(tangentAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3) + sizeof(Vector4) + sizeof(Vector2));

	// Bind bitangent to Shaders
	glEnableVertexAttribArray(bitangentAttribute);
	glVertexAttribPointer(bitangentAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3) + sizeof(Vector4) + sizeof(Vector2) + sizeof(Vector3));

	
	//
	glEnableVertexAttribArray(myShaders.uvAttribute);
	glVertexAttribPointer(myShaders.uvAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (char*)0 + sizeof(Vector3) + sizeof(Vector4));

	// Bind Texture

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, texture_id);
	glUniform1i(myShaders.textureUniform, 0);

	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, normal_map_id);
	glUniform1i(normalMapUniform, 1);

	// Bind MVP Matrix
	Matrix mvp =  getWorldMatrix() * camera->getViewMatrix() * camera->getProjectionMatrix();
	glUniformMatrix4fv(myShaders.matMVPUniform, 1, GL_FALSE, &(mvp.m[0][0]));

	// Bind light position
	glUniform3f(lightPositionUniform, lightPosition.x, lightPosition.y, lightPosition.z);
	
	// Bind light color
	glUniform3f(lightColorUniform, lightColor.x, lightColor.y, lightColor.z);


	// Bind World Matrix
	glUniformMatrix4fv(myShaders.matWorldUniform, 1, GL_FALSE, &(getWorldMatrix().m[0][0]));


	// bind camera pos
	
	Vector3 pos = camera->getPosition();
	glUniform3f(myShaders.cameraPositionUniform, pos.x, pos.y, pos.z);

	// Bind Index
	int size;
	glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);


	// Draw
	glDrawElements(GL_TRIANGLES, size / sizeof(GLushort), GL_UNSIGNED_SHORT, 0);

	// Release buffer
	glBindTexture(GL_TEXTURE_2D, 0);
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void IlluminatedObject::Update ( ESContext *esContext, float deltaTime)
{

}